<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);

namespace app\api\model;

use app\api\model\Goods as GoodsModel;
use app\api\model\jia\BuildChange as BuildChangeModel;
use app\api\model\OrderRefund as OrderRefundModel;
use app\api\model\Setting as SettingModel;
use app\api\service\order\source\Factory as OrderSourceFactory;
use app\api\service\User as UserService;
use app\common\enum\order\DeliveryStatus as DeliveryStatusEnum;
use app\common\enum\order\DeliveryType as DeliveryTypeEnum;
use app\common\enum\order\OrderStatus as OrderStatusEnum;
use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\enum\order\ReceiptStatus as ReceiptStatusEnum;
use app\common\enum\Setting as SettingEnum;use app\common\library\helper;use app\common\model\Order as OrderModel;
use app\common\service\Order as OrderService;
use app\common\service\order\Complete as OrderCompleteService;
use app\common\service\order\Refund as RefundService;
use app\common\service\qrcode\Piaoju as PiaojuService;
use app\store\service\wxapp\Message as MessageService;
use cores\exception\BaseException;
use think\facade\Db;

/**
 * 订单模型
 * Class Order
 * @package app\api\model
 */
class Order extends OrderModel
{
    /**
     * 隐藏字段
     * @var array
     */
    protected $hidden = [
        'merchant_remark',
        'transaction_id',
        'order_source_data',
        'is_settled',
        'is_delete',
        'store_id',
        'update_time',
    ];
    // 信息提示
    private string $message = '';

    /**
     * 待支付订单详情
     * @param string $orderNo 订单号
     * @return null|static
     */
    public static function getPayDetail(string $orderNo): ?Order
    {
        $where = ['order_no' => $orderNo, 'is_delete' => 0];
        return self::detail($where, ['goods', 'user']);
    }

    /**
     * 立即购买：获取订单商品列表
     * @param int $goodsId 商品ID
     * @param string $goodsSkuId 商品SKU
     * @param int $goodsNum 购买数量
     * @return mixed
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getOrderGoodsListByNow(int $goodsId, string $goodsSkuId, int $goodsNum)
    {
        // 获取商品列表
        $model     = new GoodsModel;
        $goodsList = $model->setEnableGradeMoney(false)->getListByIdsFromApi([$goodsId]);
        if ($goodsList->isEmpty()) {
            throwError('未找到商品信息');
        }
        // 隐藏冗余的属性
        $goodsList->hidden(GoodsModel::getHidden(['content', 'goods_images', 'images']));
        foreach ($goodsList as &$item) {
            // 商品sku信息
            $item['skuInfo'] = GoodsModel::getSkuInfo($item, $goodsSkuId, false);
            // 商品封面 (优先sku封面)
            $item['goods_image'] = $item['skuInfo']['goods_image'] ?: $item['goods_image'];
            // 商品单价
            $item['goods_price'] = $item['skuInfo']['goods_price'];
            // 商品购买数量
            $item['total_num'] = $goodsNum;
            // 商品SKU索引
            $item['goods_sku_id'] = $item['skuInfo']['goods_sku_id'];
            // 商品购买总金额
            $item['total_price'] = helper::bcmul($item['goods_price'], $goodsNum);
        }
        return $goodsList;
    }

    /**
     * 获取司机订单列表
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getListDriver(string $dataType = 'all'): \think\Paginator
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType3($dataType);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();

        $driver_id = Db::name('store_shop_driver')->where('user_id', $userId)->where('status', 1)->where('is_delete', 0)->value('driver_id');

        // 查询列表数据
        return $this->with(['goods.image', 'category', 'parkImage1', 'parkImage2'])
            ->where($dataTypeFilter)

            ->where('driver_id', '=', $driver_id)

            ->where('is_delete', '=', 0)

            ->order(['create_time' => 'desc'])
            ->paginate(15);
    }
    /**
     * 获取陪护师订单列表
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getListClerk(string $dataType = 'all'): \think\Paginator
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataTypeClerk($dataType);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();

        $clerk_id = Db::name('store_shop_clerk')
            ->where('user_id', $userId)->where('status', 1)->where('is_delete', 0)->value('clerk_id');

        // 查询列表数据
        return $this->with(['goods.image', 'category'])
            ->where($dataTypeFilter)

            ->where('extract_clerk_id', '=', $clerk_id)

            ->where('is_delete', '=', 0)

            ->order(['create_time' => 'desc'])
            ->paginate(15);
    }
    /**
     * 获取陪诊订单列表
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getListRunner(string $dataType = 'all'): \think\Paginator
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType30($dataType);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();

        $runner_id = Db::name('store_shop_runner')
            ->where('user_id', $userId)->where('status', 1)->where('is_delete', 0)->value('runner_id');

        // 查询列表数据
        return $this->with(['goods.image', 'category'])
            ->where($dataTypeFilter)

            ->where('runner_id', '=', $runner_id)

            ->where('is_delete', '=', 0)

            ->order(['create_time' => 'desc'])
            ->paginate(15);
    }
    /**
     * 获取主管订单列表
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getListManage(string $dataType = 'all', $keyword): \think\Paginator
    {

        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType2($dataType, $keyword);

        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();

        //负责楼层
        $manageId = Db::name('store_shop_manage')->where('user_id', $userId)->where('is_delete', 0)
            ->where('status', 1)->where('type', 1)->value('clerk_id');

        $build_ids = Db::name('jia_manage_build')->where('manage_id', $manageId)->field('build_id')
            ->select()->toArray();
        $build_ids = array_column($build_ids, 'build_id');

        $floors = Db::name('jia_manage_floor')->where('manage_id', $manageId)
            ->where('build_id', 'in', $build_ids)->field('floor')
            ->select()->toArray();
        $floors = array_column($floors, 'floor');

        //是否康护主管

        $kanghu_manage = Db::name('store_shop_manage')->where('user_id', $userId)->where('is_delete', 0)
            ->where('status', 1)->where('type', 4)->value('clerk_id');
        if ($kanghu_manage) {

            $ids1 = $this
                ->where($dataTypeFilter)

                ->where('floor_id', 'in', $floors)
                ->where('build_id', 'in', $build_ids)
                ->where('is_delete', '=', 0)
                ->where('order_type', '=', 10)->select()->toArray();
            $ids1 = array_column($ids1, 'order_id');

            $ids2 = $this
                ->where($dataTypeFilter)

                ->where('category_id', 10002)

                ->where('is_delete', '=', 0)
                ->where('order_type', '=', 10)->select()->toArray();
            $ids2 = array_column($ids2, 'order_id');

            $orderIds = array_merge($ids1, $ids2);

            // 查询列表数据
            return $this->with(['goods.image', 'category', 'extractClerk'])
                ->where($dataTypeFilter)
                ->where('order_id', 'in', $orderIds)

                ->order(['create_time' => 'desc'])
                ->paginate(15);
        } else {
            // 查询列表数据
            return $this->with(['goods.image', 'category', 'extractClerk'])
                ->where($dataTypeFilter)

                ->where('floor_id', 'in', $floors)
                ->where('build_id', 'in', $build_ids)
                ->where('is_delete', '=', 0)
                ->where('order_type', '=', 10) //陪护订单

                ->order(['create_time' => 'desc'])
                ->paginate(15);
        }

    }

    /**
     * 获取订单列表-待派单
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getListPaidan(string $dataType = 'all', $keyword): \think\Paginator
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType22($dataType, $keyword);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();

        //康护主管
        $manage10 = Db::name('store_shop_manage')->where('type', 4)->where('user_id', $userId)->find();
        $order10  = [];
        if ($manage10) {

            $order10 = Db::name('order')->where('order_type', 10)
                ->where('pay_status', 20)
                ->where('extract_clerk_id', 0)
                ->select()->toArray();
            $order10 = array_column($order10, 'order_id');
        }
        //代泊车
        $manage20 = Db::name('store_shop_manage')->where('type', 2)->where('user_id', $userId)->find();
        $order20  = [];
        if ($manage20) {
            //代泊车订单
            $order20 = Db::name('order')->where('order_type', 20)
                ->where('pay_status', 20)->where('driver_id', 0)->select()->toArray();
            $order20 = array_column($order20, 'order_id');

        }

        //陪诊，跑腿
        $manage30 = Db::name('store_shop_manage')->where('type', 3)->where('user_id', $userId)->find();
        $order30  = [];
        if ($manage30) {
            //代泊车订单
            $order30 = Db::name('order')->where('order_type', 'in', [30, 40])
                ->where('pay_status', 20)->where('runner_id', 0)->select()->toArray();
            $order30 = array_column($order30, 'order_id');
        }

        $ids = array_merge($order10, $order20, $order30);

        // 查询列表数据
        return $this->with(['goods.image', 'category'])
            ->where($dataTypeFilter)
            ->where('order_id', 'in', $ids)
            ->where('category_id', '>', 0)
            ->where('is_delete', '=', 0)
            ->order(['create_time' => 'desc'])
            ->paginate(15);
    }

/**
 * 获取用户订单列表-陪护订单
 * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
 * @return \think\Paginator
 * @throws BaseException
 * @throws \think\db\exception\DbException
 */
    public function getListShangcheng(string $dataType = 'all'): \think\Paginator
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType($dataType);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        // 查询列表数据
        return $this->with(['goods.image', 'category'])
            ->where($dataTypeFilter)
            ->where('user_id', '=', $userId)
            ->where('is_delete', '=', 0)

            ->order(['create_time' => 'desc'])
            ->paginate(15);
    }
    /**
     * 获取用户订单列表
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getList(string $dataType = 'all'): \think\Paginator
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType1($dataType);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        // 查询列表数据
        return $this->with(['goods.image', 'category', 'driver'])
            ->where($dataTypeFilter)
            ->where('user_id', '=', $userId)
            ->where('is_delete', '=', 0)

            ->order(['create_time' => 'desc'])
            ->paginate(15);
    }
    public function getListAll($date, $orderType)
    {
        $startTime = strtotime($date);
        $endTime   = strtotime($date) + 86400;

        // 查询列表数据
        return $this->with(['goods.image', 'category', 'rooms.category'])

            ->where('is_delete', '=', 0)
            ->where('order_type', '=', $orderType)
            ->where('goods_type', '=', 20)
            ->where('extract_shop_id', '=', 10005)
            ->where('pay_time', '>', 0)
            ->where('create_time', '>=', $startTime)
            ->where('create_time', '<', $endTime)

            ->order(['create_time' => 'desc'])
            ->select()->toArray();
    }

    /**
     * 获取用户订单列表-发票订单
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return \think\Paginator
     * @throws BaseException
     * @throws \think\db\exception\DbException
     */
    public function getListFapiao()
    {

        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        // 查询列表数据
        return $this->with(['goods'])
            ->where('user_id', '=', $userId)
            ->where('is_delete', '=', 0)
            ->where('is_kaipiao', '=', 0)
            ->where('pay_status', '=', 20)
            ->where('order_type', 'in', [10, 20])
            ->where('goods_type', '=', 20)
            ->order(['create_time' => 'desc'])
            ->select()->toArray();
    }

    /**
     * 取消订单
     * @return bool|mixed
     */
    public function cancel()
    {
        // 判断订单是否允许取消
        $orderSource = OrderSourceFactory::getFactory($this['order_source']);
        if (! $orderSource->checkOrderByCancel($this)) {
            $this->error = $orderSource->getError();
            return false;
        }
        if ($this['is_xufei'] == 1) {
            $this->error = '续费订单，不可取消';
            return false;
        }
        // 订单是否已支付
        $isPay = $this['pay_status'] == PayStatusEnum::SUCCESS;
        // 提示信息
        $this->message = $isPay ? '订单已申请取消，需等待后台审核' : '订单已取消成功';
        // 订单取消事件
        return $this->transaction(function () use ($isPay) {

            //$this->sendMessage($this);
            // 订单取消事件
            ! $isPay && OrderService::cancelEvent($this);
            // 更新订单状态: 已付款的订单设置为"待取消", 等待后台审核
            return $this->save(['order_status' => $isPay ? OrderStatusEnum::APPLY_CANCEL : OrderStatusEnum::CANCELLED]);
        });
    }
/**
 * 取消订单-服务
 * @return bool|mixed
 */
    public function cancel2()
    {
        // 判断订单是否允许取消
        $orderSource = OrderSourceFactory::getFactory($this['order_source']);
        if (! $orderSource->checkOrderByCancel($this)) {
            $this->error = $orderSource->getError();
            return false;
        }
        if ($this['extract_clerk_id'] > 0 || $this['manage_id'] > 0 || $this['driver_id'] > 0 || $this['runner_id'] > 0) {
            $this->error = '已派单，不可取消';
            return false;
        }
        if ($this['is_xufei'] == 1) {
            $this->error = '续费订单，不可取消';
            return false;
        }

        // 订单是否已支付
        $isPay = $this['pay_status'] == PayStatusEnum::SUCCESS;
        // 提示信息
        $this->message = $isPay ? '订单已申请取消，需等待后台审核' : '订单已取消成功';
        // 订单取消事件
        return $this->transaction(function () use ($isPay) {

            //$this->sendMessage($this);
            // 订单取消事件
            ! $isPay && OrderService::cancelEvent($this);
            // 更新订单状态: 已付款的订单设置为"待取消", 等待后台审核
            return $this->save(['order_status' => $isPay ? OrderStatusEnum::APPLY_CANCEL : OrderStatusEnum::CANCELLED]);
        });
    }

    //陪诊员-信息

    private function sendMessageRunner($order, $runnerId)
    {
        $run = Db::name('store_shop_runner')->where('runner_id', $runnerId)->find();

        $shop_name     = Db::name('store_shop')->where('shop_id', $order['extract_shop_id'])->value('shop_name');
        $category_name = Db::name('category')->where('category_id', $order['category_id'])->value('name');

        $unionid  = Db::name('user_oauth')->where('user_id', $run['user_id'])->value('unionid');
        $opend_id = Db::name('user_oauth_wxapp')->where('unionid', $unionid)->value('open_id');

        if ($opend_id) {
            // 执行发送
            $MessageService         = new MessageService;
            $content['template_id'] = 'NOoNoJK9J1xO2T6-e1-JN1cYgoZZImyoPO3gIyXswto';
            $content['page']        = 'pagesNew/order/runner/detail?orderId=' . $order['order_id'];

            $content['data']['thing5'] = $shop_name;

            $content['data']['thing1'] = $order['goods'][0]['goods_name'];
            $content['data']['const6'] = '已支付成功';

            $content['data']['thing2']        = $order['real_name'];
            $content['data']['phone_number3'] = $order['mobile'];

            //暂时注释
            $MessageService->send($opend_id, $content);
        }

        return true;

    }

    private function sendMessage($order)
    {
        $clerks = Db::name('store_shop_manage')->where('status', 1)->where('type', 4)
            ->where('is_delete', 0)->field('user_id')
            ->select()->toArray();
        $shop_name     = Db::name('store_shop')->where('shop_id', $order['extract_shop_id'])->value('shop_name');
        $build         = Db::name('jia_build')->where('build_id', $order['build_id'])->value('name');
        $goods_id      = 10006;
        $category_id   = Db::name('goods_category_rel')->where('goods_id', $goods_id)->value('category_id');
        $category_name = Db::name('category')->where('category_id', $category_id)->value('name');

        foreach ($clerks as $key => $value) {
            $unionid  = Db::name('user_oauth')->where('user_id', $value['user_id'])->value('unionid');
            $opend_id = Db::name('user_oauth_wxapp')->where('unionid', $unionid)->value('open_id');

            if ($opend_id) {
                // 执行发送
                $unionid                = Db::name('user_oauth')->where('user_id', $value['user_id'])->value('unionid');
                $opend_id               = Db::name('user_oauth_wxapp')->where('unionid', $unionid)->value('open_id');
                $MessageService         = new MessageService;
                $content['template_id'] = '4dtISUWiIraiDq7_tvnROql2qNJAWFkwi4HeZh_jEUA';
                $content['page']        = 'pagesNew/order/index';

                $content['data']['thing11']        = $shop_name;
                $content['data']['thing6']         = $build . $order['floor_id'] . '层' . $order['bed_no'];
                $content['data']['thing12']        = $category_name;
                $content['data']['time9']          = Date('Y-m-d', strtotime($order['create_time']));
                $content['data']['phone_number13'] = $order['mobile'];

                //暂时注释
                $MessageService->send($opend_id, $content);
            }
        }
    }
    /**
     * 更新停车信息
     * @return bool|mixed
     */
    public function carSave($data)
    {

        // 验证订单状态
        if ($this['order_status'] != OrderStatusEnum::NORMAL) {
            throwError('该订单不合法');
        }
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        return $this->transaction(function () use ($data, $userId) {
            // 更新订单状态,待结算
            $status = $this->save([
                'park_id'       => $data['park_id'],
                'park_name'     => $data['park_name'],
                'park_address'  => $data['address'],
                'park_file1'    => $data['uploaded1'],
                'park_file2'    => $data['uploaded2'],
                'delivery_time' => time(),
            ]);

            return $status;
        });
    }

    /**
     * 确认接车
     * @return bool|mixed
     */
    public function jieche($data)
    {

        // 验证订单状态
        if ($this['order_status'] != OrderStatusEnum::NORMAL) {
            throwError('该订单不合法');
        }
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        return $this->transaction(function () use ($data, $userId) {
            // 更新订单状态,待结算
            $status = $this->save([
                'park_code'       => rand(1000, 9999), //取车码
                'delivery_status' => 20,
                'delivery_time'   => time(),
            ]);

            return $status;
        });
    }

    /**
     * 确认接单-陪护主管
     * @return bool|mixed
     */
    public function jiedan($data)
    {

        // 验证订单状态
        if ($this['order_status'] != OrderStatusEnum::NORMAL) {
            throwError('该订单不合法');
        }
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        return $this->transaction(function () use ($data, $userId) {

            if ($data['pay_price'] == 0) {
                // 更新订单状态,待结算
                $status = $this->save([
                    'service_status' => 20,
                ]);
            } else {

                //更新
                Db::name('order_goods')
                    ->where('order_id', $this['order_id'])
                    ->update([
                        'goods_price'     => $data['goods_price'],
                        'total_num'       => $data['total_num'],
                        'total_price'     => $data['goods_price'] * $data['total_num'],
                        'total_pay_price' => $data['goods_price'] * $data['total_num'],

                    ]);
                //发起协议

                // 更新订单状态
                $status = $this->save([
                    'pay_status'     => 10,
                    'is_bed'         => $data['is_bed'],
                    'bed_fee'        => $data['bed_fee'],
                    'bed_no'         => isset($data['bed_no']) ? $data['bed_no'] : '',
                    'is_continue'    => isset($data['is_continue']) ? $data['is_continue'] : 0,
                    'day'            => $data['total_num'],
                    'start_date'     => $data['start_date'],
                    'end_date'       => $data['end_date'],
                    'peihu_time'     => $data['start_time'],
                    'house_id'       => $data['house_id'] != null ? $data['house_id'] : 0,
                    'sex'            => $data['sex'],
                    'service_status' => 10,
                    'manage_id'      => $userId,
                    'pay_price'      => $data['pay_price'],
                    'total_price'    => $this['total_price'] + $data['pay_price'],
                    'order_no'       => $this->orderNo(),
                ]);
            }

            return $status;
        });
    }

    public function buildChange($data)
    {

        $this->save([
            'floor'           => $data['floor'],
            'extract_shop_id' => $data['extract_shop_id'],
            'floor_id'        => $data['floor_id'],
            'floor'           => $data['floor'],
            'build_id'        => $data['build_id'],
            'room'            => $data['room'],
            'room_id'         => $data['room_id'],
            'house_id'        => $data['house_id'] ? $data['house_id'] : 0,
            'bed_no'          => $data['bed_no'],

        ]);

        $model = new BuildChangeModel;
        $model->add($this['order_id'], $data);

    }

    /**
     * 用户续费
     * @return bool|mixed
     */
    public function xufeiUser($data)
    {

        // 验证订单状态
        if ($this['order_status'] == 30) {
            throwError('该订单已经完成，请从新下单');
        }

        return $this->transaction(function () use ($data) {

            //更新
            // Db::name('order_goods')
            // 	->where('order_id', $this['order_id'])
            // 	->inc('total_num')
            // 	->update();

            // 更新订单状态
            $status = $this->save([
                'pay_status'     => 10,
                'service_status' => 20,
                'is_xufei'       => 1,
                'pay_time'       => 0,
                'bed_fee_xu'     => $data['bed_fee'],
                'is_bed'         => $data['bed_fee'] > 0 ? 1 : 0,
                'xufei_day'      => $data['day'],
                'end_date'       => $data['end_date'],
                'total_price'    => $this['total_price'] + $data['pay_price'],
                'pay_price'      => $data['pay_price'],
                'order_no'       => $this->orderNo(),
            ]);

            return $status;
        });
    }
    /**
     * 主管续费
     * @return bool|mixed
     */
    public function xufei($data)
    {

        // 验证订单状态
        if ($this['order_status'] == 30) {
            throwError('该订单已经完成');
        }

        return $this->transaction(function () use ($data) {

            //更新
            // Db::name('order_goods')
            // 	->where('order_id', $this['order_id'])
            // 	->inc('total_num')
            // 	->update();

            // 更新订单状态
            $status = $this->save([
                'pay_status'     => 10,
                'service_status' => 20,
                'bed_no'         => $data['bed_no'],
                'is_xufei'       => 1,
                'is_bed'         => $data['bed_fee'] > 0 ? 1 : 0,
                'pay_time'       => 0,
                'bed_fee_xu'     => $data['bed_fee'],
                'xufei_day'      => $data['total_num'],
                'end_date'       => $data['end_date'],
                'xufei_price'    => $data['pay_price'],
                'total_price'    => $this['total_price'] + $data['pay_price'],
                'pay_price'      => $data['pay_price'],
                'peihu_time'     => $data['start_time'],
                'order_no'       => $this->orderNo(),
            ]);

            //更新费用
            Db::name('order_goods')->where('order_id', $this['order_id'])
                ->update(['goods_price' => $data['goods_price']]);

            return $status;
        });
    }

    /**
     * 主管-修改金额
     * @return bool|mixed
     */
    public function editPrice($data)
    {

        // 验证订单状态
        if ($this['order_status'] == 30) {
            throwError('该订单已经完成');
        }
        if ($this['pay_status'] == 20) {
            throwError('该订单已经支付');
        }
        return $this->transaction(function () use ($data) {

            //更新

            if ($this['is_xufei'] == 1) {
                if ($this['is_bed'] == 1 && $data['is_bed'] == 0) {
                    $bed_fee = $this['bed_fee'] - $data['total_num'] * 3;
                }
                if ($this['is_bed'] == 0 && $data['is_bed'] == 1) {
                    $bed_fee = $this['bed_fee'] + $data['total_num'] * 3;
                }
                if ($this['is_bed'] == $data['is_bed']) {
                    $bed_fee = $this['bed_fee'];
                }

                // 更新订单状态
                $status = $this->save([

                    'total_price' => $this['total_price'] - $this['xufei_price'] + $data['pay_price'],
                    'is_bed'      => $data['is_bed'],
                    'bed_fee'     => $bed_fee,
                    'xufei_price' => $data['pay_price'],
                    'pay_price'   => $data['pay_price'],
                ]);
            } else {

                if ($data['is_bed'] == 0) {
                    $bed_fee = 0;
                }
                if ($data['is_bed'] == 1) {
                    $bed_fee = $data['total_num'] * 3;
                }

                // 更新订单状态
                $status = $this->save([

                    'total_price' => $data['pay_price'],
                    'is_bed'      => $data['is_bed'],
                    'bed_fee'     => $bed_fee,
                    'xufei_price' => 0,
                    'pay_price'   => $data['pay_price'],
                ]);
            }

            //更新费用
            Db::name('order_goods')->where('order_id', $this['order_id'])
                ->update(['goods_price' => $data['goods_price']]);

            return $status;
        });
    }
    /**
     * 派单-陪诊
     * @return bool|mixed
     */
    public function paidanRunner($data)
    {

        // 验证订单状态
        if ($this['order_status'] != 10) {
            throwError('订单已取消或完成');
        }
        if ($this['runner_id'] > 0) {
            throwError('该订单已派单');
        }

        //查看当前司机状态
        $driver = Db::name('store_shop_runner')->where('runner_id', $data['runner_id'])->where('is_delete', 0)
            ->where('work_status', 10)->find();
        // if(!$driver){
        // 		throwError('该陪诊员非空闲状态');
        // }

        // 当前用户ID
        $userId    = UserService::getCurrentLoginUserId();
        $manage_id = Db::name('store_shop_manage')->where('user_id', $userId)->where('type', 3)->value('clerk_id');

        //更新司机状态

        Db::name('store_shop_runner')->where('runner_id', $data['runner_id'])->update(['work_status' => 20]);

        // 更新订单状态
        $status = $this->save([
            'paidaner_id'    => $manage_id,
            'service_status' => 10,
            'paidan_time'    => time(),
            'runner_id'      => $data['runner_id'],
        ]);
        //发送信息
        $this->sendMessageRunner($this, $data['runner_id']);

        return $status;

    }

    /**
     * 派单-泊车
     * @return bool|mixed
     */
    public function paidanPark($data)
    {

        // 验证订单状态
        if ($this['order_status'] != 10) {
            throwError('订单已取消或完成');
        }
        if ($this['driver_id'] > 0) {
            throwError('该订单已派单');
        }

        //查看当前司机状态
        $driver = Db::name('store_shop_driver')->where('driver_id', $data['driver_id'])->where('is_delete', 0)
            ->where('work_status', 10)->find();
        // if(!$driver){
        // 		throwError('该司机非空闲状态');
        // }

        // 当前用户ID
        $userId    = UserService::getCurrentLoginUserId();
        $manage_id = Db::name('store_shop_manage')->where('user_id', $userId)->where('type', 2)->value('clerk_id');

        //更新司机状态

        Db::name('store_shop_driver')->where('driver_id', $data['driver_id'])->update(['work_status' => 20]);

        // 更新订单状态
        $status = $this->save([

            'service_status' => 10,
            'paidaner_id'    => $manage_id,
            'paidan_time'    => time(),
            'driver_id'      => $data['driver_id'],
        ]);

        return true;
    }
    /**
     * 派单-陪护
     * @return bool|mixed
     */
    public function paidanPeihu($data)
    {

        // 验证订单状态
        if ($this['order_status'] != 10) {
            throwError('订单已取消或完成');
        }
        if ($this['pandan_time'] > 0) {
            throwError('该订单已派单');
        }

        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();

        $manage_id = Db::name('store_shop_manage')->where('user_id', $userId)->where('type', 4)->value('clerk_id');

        $total_price = $this['day'] * $data['day_price'];
        $shengyu     = $this['total_price'] - $this['bed_fee'] - $this['money_total'];

        if ($total_price > $shengyu) {

            throwError('工资，超过可结算金额');
        }
        $clerk_id = 0;
        $group_id = 0;
        if (isset($data['is_group']) && $data['is_group'] == 10) {
            //班组
            $group_id = $data['groupId'];
        } else {
            $clerk_id = $data['extract_clerk_id'];
        }

        return $this->transaction(function () use ($data, $manage_id, $clerk_id, $group_id) {

            $status = $this->save([
                'extract_clerk_id' => $clerk_id, // 核销员
                'group_id'         => $group_id,
                'day_price'        => $data['day_price'], //日薪
                'hour_price'       => $data['hour_price'],
                'service_status'   => 10,
                'paidan_time'      => time(),
                'paidaner_id'      => $manage_id,
            ]);
            if ($clerk_id > 0) {
                //陪护中
                Db::name('store_shop_clerk')->where('clerk_id', $data['extract_clerk_id'])->update(['work_status' => 20]);
                //非班组
                $order['order_id']    = $this['order_id'];
                $order['money']       = $data['day_price'];
                $order['hour_price']  = $data['hour_price'];
                $order['clerk_id']    = $clerk_id;
                $order['store_id']    = $this['store_id'];
                $order['create_time'] = time();
                $dd[]                 = $order;

            } else {
                $clerkIds = Db::name('store_shop_clerk_group')->where('id', $data['groupId'])->value('clerk_ids');
                $clerkIds = json_decode($clerkIds);
                //班组
                Db::name('store_shop_clerk')->where('clerk_id', 'in', $clerkIds)->update(['work_status' => 20]);

                foreach ($clerkIds as $key => $clerk_id) {
                    $order['order_id']    = $this['order_id'];
                    $order['money']       = $data['day_price'];
                    $order['hour_price']  = $data['hour_price'];
                    $order['clerk_id']    = $clerk_id;
                    $order['store_id']    = $this['store_id'];
                    $order['create_time'] = time();
                    $dd[]                 = $order;
                }
            }
            //护理员记录
            Db::name('order_clerk')->insertAll($dd);

            return $status;
        });

    }
    /**
     * 完成-陪护订单
     * @return bool|mixed
     */
    public function complate($data)
    {

        // 验证订单状态
        if ($this['order_status'] != OrderStatusEnum::NORMAL || $this['pay_time'] == 0) {
            throwError('该订单不合法');
        }

        return $this->transaction(function () use ($data) {

            if ($this['order_type'] == 10) {

                //查询服务中订单
                $count = Db::name('order')->where('extract_clerk_id', $this['extract_clerk_id'])
                    ->where('order_status', '=', 10)->count();
                if ($count == 1) {
                    Db::name('store_shop_clerk')->where('clerk_id', $this['extract_clerk_id'])
                        ->update(['work_status' => 10]);
                }
                $out_price = 0;
                $out_hour  = 0;

                $total_price = $this['total_price'] - $this['bed_fee'] - $this['money_total'];
                // if (isset($data['real_hour'])) {
                //     $total_price += (int) $data['real_hour'] * $this['hour_price'] * 2;
                // }
                $out_price = (int) $data['out_hour'] * $this['hour_price'] * 2;
                $out_hour  = $data['out_hour'];

                $capital['money'] = $data['clerk_money'];

                // if ($this['is_bed']) {
                //     $fee = $this['bed_fee'] / $this['day'];
                //     $total_price += $fee * $data['real_day'];
                // }

                if ($data['refund_price'] > 0) {
                    if ($data['refund_price'] + $capital['money'] > $total_price) {
                        throwError('退款金额+工资，超过可结算金额');
                    }

                    //最后一次支付金额
                    $last = Db::name('order_pay_log')->where('order_id', $this['order_id'])
                        ->order('trade_id desc')->find();

                    if ($data['refund_price'] > $last['pay_price']) {
                        throwError('退款金额大于最后一次支付金额');
                    }

                    // 执行退款操作
                    if (! (new RefundService)->handle($this, (string) $data['refund_price'])) {
                        throwError('执行订单退款失败');
                    }

                }

                if ($this['is_settle'] == 1) {

                } else {
                    // 工资明细

                    $capital['store_id']    = $this['store_id'];
                    $capital['clerk_id']    = $this['extract_clerk_id'];
                    $capital['out_hour']    = $data['out_hour'];
                    $capital['order_id']    = $this['order_id'];
                    $capital['real_day']    = $data['real_day'];
                    $capital['real_hour']   = $data['real_hour'];
                    $capital['create_time'] = time();
                    $capital['flow_type']   = 10;
                    $capital['describe']    = '陪护工资：' . $this['order_no'];
                    Db::name('store_shop_clerk_capital')->insert($capital);

                    //产生票据

                    $Qrcode                = new PiaojuService($this);
                    $imageUrl              = $Qrcode->getImage();
                    $piaoju['path']        = $imageUrl;
                    $piaoju['order_id']    = $this['order_id'];
                    $piaoju['store_id']    = $this['store_id'];
                    $piaoju['create_time'] = time();
                    $piaoju['user_id']     = $this['user_id'];
                    $piaoju['name']        = $this['goods'][0]['goods_name'];

                    Db::name('order_piaoju')->insert($piaoju);
                }

                $money_total = $this['money_total'] + $data['clerk_money'];

                $this->save([
                    'order_status' => 30,
                    'is_settle'    => 1,
                    'real_hour'    => $data['real_hour'] + $this['real_hour'],
                    'out_hour'     => $data['out_hour'] + $this['out_hour'],
                    'out_price'    => $out_price,
                    'real_day'     => $data['real_day'] + $this['real_day'],
                    'money'        => $capital['money'],
                    'money_total'  => $money_total]);

            }

            if ($this['order_type'] == 20) {

                $this->save([
                    'park_survey' => $data['park_content'],
                    'park_manyi'  => $data['manyi'],
                ]);
            }

            // 更新订单状态
            $status = $this->save([
                'order_status'   => 30,
                'service_status' => 20,
                'refund_price'   => isset($data['refund_price']) ? $data['refund_price'] : 0,
            ]);

            return $status;
        });
    }
    /**
     * 完成-司机操作
     * @return bool|mixed
     */
    public function complatePark($data)
    {

        // 验证订单状态
        if ($this['order_status'] != OrderStatusEnum::NORMAL || $this['pay_time'] == 0) {
            throwError('该订单不合法');
        }

        return $this->transaction(function () use ($data) {

            if ($data['park_fee'] == 0) {
                //不超时，不需要额外费用
                // 更新订单状态
                $status = $this->save([
                    'order_status'   => 10,
                    'service_status' => 20,
                    'receipt_status' => 20,
                    'end_date'       => $data['end_date'], //还车时间
                    'park_fee'       => $data['park_fee'],
                    'park_time'      => $data['park_time'],
                ]);
                //查询服务中订单
                $count = Db::name('order')->where('driver_id', $this['driver_id'])
                    ->where('receipt_status', '<', 20)->count();
                if ($count == 0) {
                    Db::name('store_shop_driver')->where('driver_id', $this['driver_id'])->update(['work_status' => 10]);
                }

            } else {
                $status = $this->save([
                    'service_status' => 20,
                    'end_date'       => $data['end_date'], //还车时间
                    'park_fee'       => $data['park_fee'],
                    'park_time'      => $data['park_time'],
                    'pay_status'     => 10,
                    'pay_price'      => $data['park_fee'],
                    'total_price'    => $this['total_price'] + $data['park_fee'],
                    'order_no'       => $this->orderNo(),
                    'receipt_status' => 20,
                ]);
                //查询服务中订单
                $count = Db::name('order')->where('driver_id', $this['driver_id'])
                    ->where('receipt_status', '<', 20)->count();
                if ($count == 0) {
                    Db::name('store_shop_driver')->where('driver_id', $this['driver_id'])->update(['work_status' => 10]);
                }
            }

            return $status;
        });
    }
    /**
     * 完成-陪诊操作
     * @return bool|mixed
     */
    public function complateRunner($data)
    {

        // 验证订单状态
        if ($this['order_status'] != OrderStatusEnum::NORMAL || $this['pay_time'] == 0) {
            throwError('该订单不合法');
        }

        return $this->transaction(function () use ($data) {

            if ($data['park_fee'] == 0) {
                //不超时，不需要额外费用
                // 更新订单状态
                $status = $this->save([
                    'order_status'   => 10,
                    'service_status' => 20,
                    'receipt_status' => 20,
                    'order_status'   => 30,
                    'end_date'       => $data['end_date'],
                    'peihu_time'     => $data['start_date'],
                    'park_fee'       => $data['park_fee'],
                    'park_time'      => $data['park_time'],
                ]);

                //查询服务中订单
                $count = Db::name('order')->where('runner_id', $this['runner_id'])
                    ->where('receipt_status', '<', 20)->count();
                if ($count == 0) {
                    Db::name('store_shop_runner')->where('runner_id', $this['runner_id'])->update(['work_status' => 10]);
                }
            } else {
                $status = $this->save([
                    'service_status' => 20,
                    'end_date'       => $data['end_date'],
                    'peihu_time'     => $data['start_date'],
                    'park_fee'       => $data['park_fee'],
                    'park_time'      => $data['park_time'],
                    'pay_status'     => 10,
                    'pay_price'      => $data['park_fee'],
                    'total_price'    => $this['total_price'] + $data['park_fee'],
                    'order_no'       => $this->orderNo(),
                    'receipt_status' => 20,
                ]);

                //查询服务中订单
                $count = Db::name('order')->where('runner_id', $this['runner_id'])
                    ->where('receipt_status', '<', 20)->count();
                if ($count == 0) {
                    Db::name('store_shop_runner')->where('runner_id', $this['runner_id'])->update(['work_status' => 10]);
                }
            }

            return $status;
        });
    }

    /**
     * 确认收货
     * @return bool|mixed
     */
    public function receipt()
    {
        // 验证订单是否合法
        // 条件1: 订单必须已发货
        // 条件2: 订单必须未收货
        if (
            $this['delivery_status'] != DeliveryStatusEnum::DELIVERED
            || $this['receipt_status'] != ReceiptStatusEnum::NOT_RECEIVED
        ) {
            $this->error = '该订单不合法';
            return false;
        }
        return $this->transaction(function () {
            // 更新订单状态
            $status = $this->save([
                'receipt_status' => ReceiptStatusEnum::RECEIVED,
                'receipt_time'   => time(),
                'order_status'   => OrderStatusEnum::COMPLETED,
            ]);
            // 执行订单完成后的操作
            $OrderCompleteService = new OrderCompleteService();
            $OrderCompleteService->complete([$this], static::$storeId);
            return $status;
        });
    }

    /**
     * 获取当前用户订单数量
     * @param string $dataType 订单类型 (all全部 payment待付款 deliver待发货 received待收货 comment待评价)
     * @return int
     * @throws BaseException
     */
    public function getCount(string $dataType = 'all'): int
    {
        // 设置订单类型条件
        $dataTypeFilter = $this->getFilterDataType($dataType);
        // 当前用户ID
        $userId = UserService::getCurrentLoginUserId();
        // 查询数据
        return $this->where('user_id', '=', $userId)
            ->where('order_status', '<>', 20)
            ->where($dataTypeFilter)
            ->where('is_delete', '=', 0)
            ->count();
    }
    /**
     * 设置订单类型条件
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType(string $dataType): array
    {
        // 筛选条件
        $filter = [];

        // 订单数据类型
        switch ($dataType) {
            case 'all':
                break;
            case 'payment':
                $filter[] = ['pay_status', '=', PayStatusEnum::PENDING];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case 'delivery':
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],
                    ['delivery_status', '<>', DeliveryStatusEnum::DELIVERED],
                    ['order_status', 'in', [OrderStatusEnum::NORMAL, OrderStatusEnum::APPLY_CANCEL]],
                ];
                break;
            case 'received':
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],
                    ['delivery_status', '=', DeliveryStatusEnum::DELIVERED],
                    ['receipt_status', '=', ReceiptStatusEnum::NOT_RECEIVED],
                    ['order_status', '=', OrderStatusEnum::NORMAL],
                ];
                break;
            case 'comment':
                $filter = [
                    ['is_comment', '=', 0],
                    ['order_status', '=', OrderStatusEnum::COMPLETED],
                ];
                break;
        }
        $filter[] = ['goods_type', '=', 10];
        return $filter;
    }
    /**
     * 设置订单类型条件
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType1(string $dataType): array
    {
        // 筛选条件
        $filter = [];

        // 订单数据类型
        switch ($dataType) {
            case 'all':
                break;
            case 'payment':
                $filter[] = ['pay_status', '=', PayStatusEnum::PENDING];
                $filter[] = ['service_status', '>', 0];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case 'delivery':
                $filter = [

                    ['service_status', '=', 0],
                    ['order_status', 'in', [OrderStatusEnum::NORMAL, OrderStatusEnum::APPLY_CANCEL]],
                ];
                break;
            case 'received':
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],

                    ['order_status', '=', OrderStatusEnum::NORMAL],
                ];
                break;
            case 'comment':
                $filter = [
                    ['is_comment', '=', 0],
                    ['order_status', '=', OrderStatusEnum::COMPLETED],
                ];
                break;
        }
        $filter[] = ['goods_type', '=', 20];
        return $filter;
    }
    /**
     * 设置订单类型条件-待派单
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType22(string $dataType, $keyword): array
    {
        // 筛选条件
        $filter   = [];
        $filter[] = ['pay_status', '=', 20];
        $filter[] = ['paidan_time', '=', 0];
        // $filter[] = ['service_status', '=', 0];
        $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];

        switch ($dataType) {
            case 'all':
                break;
            case 'park':
                $filter[] = ['order_type', '=', 20];

                break;
            case 'peihu':
                $filter[] = [

                    ['order_type', '=', 10],
                ];
                break;
            case 'run':
                $filter[] = [

                    ['order_type', 'in', [30, 40]],
                ];
                break;

        }
        if (! empty($keyword)) {

            $filter[] = ['real_name|mobile', 'like', '%' . $keyword . '%'];
        }
        return $filter;
    }
    /**
     * 设置订单类型条件-主管端
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType2(string $dataType, $keyword): array
    {
        // 筛选条件
        $filter = [];

        // 订单数据类型
        switch ($dataType) {
            case 'all':
                break;
            case 'payment':
                $filter[] = ['pay_status', '=', PayStatusEnum::PENDING];
                $filter[] = ['service_status', '=', 10];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case 'delivery':
                $filter = [
                    ['pay_status', '=', PayStatusEnum::PENDING],
                    ['service_status', '=', 0],
                    ['order_status', '=', 10],
                ];
                break;
            case 'received':
                $filter = [
                    ['service_status', '>', 0],
                    ['pay_status', '=', 20],
                    ['order_status', '=', OrderStatusEnum::NORMAL],
                ];
                break;
            case 'comment':
                $filter = [
                    ['is_comment', '=', 0],
                    ['order_status', '=', OrderStatusEnum::COMPLETED],
                ];
                break;
        }
        if (! empty($keyword)) {

            $filter[] = ['real_name|mobile', 'like', '%' . $keyword . '%'];
        }
        return $filter;
    }

    /**
     * 设置订单类型条件-陪护师端
     * @param string $dataType
     * @return array
     */
    private function getFilterDataTypeClerk(string $dataType): array
    {
        // 筛选条件
        $filter = [];
        // 订单数据类型
        switch ($dataType) {
            case 'all':
                break;
            case 'daifuwu':
                $filter[] = ['pay_status', '=', 20];
                $filter[] = ['service_status', '=', 10];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case 'complate':
                $filter = [
                    ['order_status', '=', OrderStatusEnum::COMPLETED],
                ];
                break;
        }
        return $filter;
    }

    /**
     * 设置订单类型条件-陪诊端
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType30(string $dataType): array
    {
        // 筛选条件
        $filter = [];
        // 订单数据类型
        switch ($dataType) {
            case 'all':
                break;
            case 'daichuli':
                $filter[] = ['pay_status', '=', 20];
                $filter[] = ['service_status', '=', 10];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case 'daiwancheng':
                $filter = [
                    ['receipt_status', '=', 10],
                    ['order_status', '=', 10],
                ];
                break;

            case 'complate':
                $filter = [

                    ['order_status', '=', OrderStatusEnum::COMPLETED],
                ];
                break;
        }
        return $filter;
    }
    /**
     * 设置订单类型条件-司机端
     * @param string $dataType
     * @return array
     */
    private function getFilterDataType3(string $dataType): array
    {
        // 筛选条件
        $filter = [];
        // 订单数据类型
        switch ($dataType) {
            case 'all':
                break;
            case 'payment':
                $filter[] = ['pay_status', '=', PayStatusEnum::PENDING];
                $filter[] = ['service_status', '=', 10];
                $filter[] = ['order_status', '=', OrderStatusEnum::NORMAL];
                break;
            case 'daijieche':
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],
                    ['delivery_status', '=', 10],
                    ['order_status', 'in', [OrderStatusEnum::NORMAL, OrderStatusEnum::APPLY_CANCEL]],
                ];
                break;
            case 'daihuan':
                $filter = [
                    ['pay_status', '=', PayStatusEnum::SUCCESS],
                    ['delivery_status', '=', 20],
                    ['order_status', '=', OrderStatusEnum::NORMAL],
                ];
                break;
            case 'complate':
                $filter = [
                    ['is_comment', '=', 0],
                    ['order_status', '=', OrderStatusEnum::COMPLETED],
                ];
                break;
        }
        return $filter;
    }
    /**
     * 获取用户订单详情(含关联数据)
     * @param int $orderId 订单ID
     * @param bool $onlyCurrentUser 只查询当前登录用户的记录
     * @return Order|array|null
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getUserOrderDetail(int $orderId, bool $onlyCurrentUser = false)
    {
        // 查询订单记录
        $with  = ['goods' => ['image', 'refund'], 'log', 'delivery.express', 'category', 'extractShop', 'build', 'driver', 'parkImage1', 'parkImage2', 'address', 'images.file', 'runner', 'extractClerk'];
        $order = static::getDetail($orderId, $with, $onlyCurrentUser);
        // 附加数据
        $order = static::related($order, ['address']);
        // 该订单是否允许申请售后
        $order['isAllowRefund'] = static::isAllowRefund($order);
        return $order;
    }

    /**
     * 获取未支付的订单详情(用于订单支付)
     * @param int $orderId 订单ID
     * @return array
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getUnpaidOrderDetail(int $orderId): array
    {
        // 获取订单详情
        $orderInfo = static::getDetail($orderId);
        // 验证订单状态
        if ($orderInfo['order_status'] != OrderStatusEnum::NORMAL) {
            throwError('当前订单状态不允许支付');
        }
        // 未支付订单的过期时间
        $orderCloseTime = SettingModel::getOrderCloseTime() * 60 * 60;
        // 订单超时截止时间
        $expirationTime = $orderInfo->getData('create_time') + $orderCloseTime;
        if ($orderCloseTime > 0 && $expirationTime <= time()) {
            //throwError('当前订单支付已超时，请重新下单');
        }
        // 仅返回需要的数据
        return [
            'orderId'        => $orderInfo['order_id'],
            'order_no'       => $orderInfo['order_no'],
            'pay_price'      => $orderInfo['pay_price'],
            'pay_status'     => $orderInfo['pay_status'],
            'order_status'   => $orderInfo['order_status'],
            'create_time'    => $orderInfo['create_time'],
            'showExpiration' => $orderCloseTime > 0,
            'expirationTime' => format_time($expirationTime),
        ];
    }

    /**
     * 获取用户订单详情(仅订单记录)
     * @param int $orderId
     * @param array $with
     * @param bool $onlyCurrentUser 只查询当前登录用户的记录
     * @return Order|array|null
     * @throws BaseException
     */
    public static function getDetail(int $orderId, array $with = [], bool $onlyCurrentUser = false)
    {
        // 查询条件
        $where                                = ['order_id' => $orderId];
        $onlyCurrentUser && $where['user_id'] = UserService::getCurrentLoginUserId();
        // 查询订单记录
        $order = static::detail($where, $with);
        empty($order) && throwError('订单不存在');
        return $order;
    }

    /**
     * 判断当前订单是否允许核销
     * @param static $order
     * @return bool
     */
    public function checkExtractOrder(self $order): bool
    {
        if (
            $order['pay_status'] == PayStatusEnum::SUCCESS
            && $order['delivery_type'] == DeliveryTypeEnum::EXTRACT
            && $order['delivery_status'] == DeliveryStatusEnum::NOT_DELIVERED
        ) {
            return true;
        }
        $this->setError('很抱歉，该订单不能被核销');
        return false;
    }

    /**
     * 获取当前用户待处理的订单数量
     * @return array
     * @throws BaseException
     */
    public function getTodoCounts(): array
    {
        return [
            'payment'  => $this->getCount('payment'),             // 待付款的订单
            'delivery' => $this->getCount('delivery'),            // 待发货的订单
            'received' => $this->getCount('received'),            // 待收货的订单
            'refund'   => OrderRefundModel::getCountByUnderway(), // 进行中的售后单
        ];
    }

    // 返回提示信息
    public function getMessage(): string
    {
        return $this->message;
    }

    /**
     * 当前订单是否允许申请售后
     * @param Order $order
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private static function isAllowRefund(self $order): bool
    {
        // 不能是未发货的订单
        if ($order['delivery_status'] == DeliveryStatusEnum::NOT_DELIVERED) {
            return false;
        }
        // 允许申请售后期限(天)
        $refundDays = SettingModel::getItem(SettingEnum::TRADE)['order']['refund_days'];
        // 不允许售后
        if ($refundDays == 0) {
            return false;
        }
        // 当前时间超出允许申请售后期限
        if (
            $order['receipt_status'] == ReceiptStatusEnum::RECEIVED
            && time() > ($order->getData('receipt_time') + ((int) $refundDays * 86400))
        ) {
            return false;
        }
        return true;
    }

    /**
     * 更新订单来源记录ID
     * @param int $orderId
     * @param int $soureId
     * @return bool
     */
    public static function updateOrderSourceId(int $orderId, int $soureId): bool
    {
        return static::updateOne(['order_source_id' => $soureId], $orderId);
    }
}
